//
//  ThreadCache.cpp
//  ThreadCache
//
//  Created by 卜绎皓 on 2023/1/31.
//

#include "ThreadCache.hpp"
#include "CentralCache.hpp"

//从中心缓存获取对象
void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    //慢开始反馈调节算法
    //1、最开始不会一次向central cache一次批量要太多，因为要太多了可能用不完
    //2、如果你不断有size大小的内存需求，那么batchNum就会不断增长，直到上限
    
    size_t batchNum = min(_freeLists[index].MaxSize(),SizeClass::NumMoveSize(size));
    if(_freeLists[index].MaxSize() == batchNum)
    {
        _freeLists[index].MaxSize() += 1;
    }
    
    void* start = nullptr;
    void* end = nullptr;
    
    size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start,end,batchNum,size);
    
    assert(actualNum > 1);//至少有一个
    
    if(actualNum == 1)//申请到对象的个数是一个，则直接将这一个对象返回即可
    {
        assert(start == end);
        return start;
    }
    else//申请到对象的个数是多个，还需要将剩下的对象挂到thread cache中对应的哈希桶中
    {
        _freeLists[index].PushRange(NextObj(start),end);
        return start;
    }
}



//申请内存对象
void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);
    size_t alignSize = SizeClass::RoundUp(size);
    size_t index = SizeClass::Index(size);
    
    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else
    {
        return FetchFromCentralCache(index,alignSize);
    }
}
